// pages/songDetail/songDetail.js
import PubSub from 'pubsub-js';
import request from '../../utils/request';
import moment from 'moment';

// 获取全局实例
let appInstance = getApp();
Page({

    /**
     * 页面的初始数据
     */
    data: {
        isPlay: false, //音乐是否播放
        MusicDetail: {}, //音乐详情对象
        musicId: '', //音乐id
        musicLink: '', //音乐的链接
        currentTime: '00:00', //实时时间
        durationTime: '00:00', //总时长
        currentWidth: 0, //实时进度条的宽度

    },

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad: function(options) {
        // options：用于接收路由跳转的query参数
        // 原生小程序中路由传参，对参数的长度有限制，如果参数长度过长会自动截取掉。
        let musicId = options.musicId;
        this.setData({ musicId });
        // 获取音乐详情的回调函数
        this.getMusicDetail(musicId);

        /* 
         问题：如果用户操作系统的控制音乐播放/暂停的按钮的时候，页面不知道，导致页面显示是否播放的状态和真实的音乐播放状态不一致。

            解决方案：
            1、控制音频的实例 backAudioManager 去监听音乐的播放和暂停
        */

        // 判断当前页面音乐是否在播放
        if (appInstance.globalData.isMusicPlay && appInstance.globalData.musicId === musicId) {
            // 修改当前页面的音乐播放状态为true
            this.setData({
                isPlay: true
            })
        }

        // 创建控制音乐播放的实例  
        this.backAudioManager = wx.getBackgroundAudioManager();
        // 监听音乐播放
        this.backAudioManager.onPlay(() => {
            this.changePlayState(true);

            // 在音乐播放的时候修改全局音乐播放的音乐Id
            appInstance.globalData.musicId = this.data.musicId;
        });
        // 监听音乐暂停
        this.backAudioManager.onPause(() => {
            this.changePlayState(false);
        });
        // 监听音乐停止
        this.backAudioManager.onStop(() => {
            this.changePlayState(false)
        });


        // 订阅来自recommendSong 页面发布的musicId消息
        // PubSub.subscribe('musicId', (msg, musicId) => {
        //     console.log(musicId);
        //     this.setData({
        //         musicId
        //     });

        //     // 由于 onLoad 只执行一次，所以不用取消订阅，但是回退又进来会再次调用onLoad记载，所以还是要取消订阅
        //     // 取消订阅
        //     // PubSub.unsubscribe('musicId')
        // })

        // 监听音乐实时播放的进度
        this.backAudioManager.onTimeUpdate(() => {
            // 判断当前播放的歌曲是否是当前页面的歌曲，如果当前播放的音乐id musicId 跟 全局data app.js中的 musicId 相等，则进度条和，歌曲当前时间变化，否则不变化。
            if (appInstance.globalData.musicId === musicId) {
                // console.log('总时长：', this.backAudioManager.duration);
                // console.log('实时的时长：', this.backAudioManager.currentTime);
                // 格式化实时播放时间
                // moment计算的单位是ms,这里监听到的是s，所以要 *1000 转换为ms
                let currentTime = moment(this.backAudioManager.currentTime * 1000).format('mm:ss');
                // console.log(currentTime);
                // currentWidth(实时宽度)/总的宽度 = 实时时间/总时间
                let currentWidth = this.backAudioManager.currentTime / this.backAudioManager.duration * 450;
                this.setData({
                    currentTime,
                    currentWidth
                });
            }
        });

        // 监听歌曲自然播放结束，然后调用下一首
        this.backAudioManager.onEnded(() => {
            // 自动切换至下一首音乐，并且自动播放。

            // 发布消息数据给 recommendSong 页面
            // 这里由于是切换下一首，所以type为 'next' 
            PubSub.publish('switchType', 'next');

            // 订阅来自recommendSong 页面发布的musicId消息
            PubSub.subscribe('musicId', (msg, musicId) => {
                // console.log(musicId);
                this.setData({
                    musicId
                });

                // 获取音乐的详情信息
                this.getMusicDetail(musicId);

                // 自动播放当前的音乐
                // 切歌的时候没传 musicLink ，所以切歌的时候会进入musicControl方法的 if (!musicLink)中
                this.musicControl(true, musicId);

                // 取消订阅
                PubSub.unsubscribe('musicId')
            });

            // 将实时进度条长度还原成0
            this.setData({
                currentWidth: 0,
                currentTime: '00:00', //实时时间也归零
            });
        });
    },

    // 修改播放状态的功能函数
    changePlayState(isPlay) {
        // 修改音乐是否播放的状态
        this.setData({
            isPlay
        });
        // 动态修改全局数据的音乐播放状态
        appInstance.globalData.isMusicPlay = isPlay;
    },

    // 获取音乐详情的回调函数
    async getMusicDetail(musicId) {
        let result = await request('/song/detail', { ids: musicId });

        let durationTime = moment(result.songs[0].dt).format('mm:ss');
        //单位是ms毫秒
        this.setData({
            MusicDetail: result.songs[0],
            durationTime
        });
        wx.setNavigationBarTitle({
            // 这里要把title:''中的''去掉，不然传的是字符串，而不是变量
            title: this.data.MusicDetail.name
        });
    },

    // 点击音乐播放或者暂停按钮的回调函数
    handlerMusicPlay() {
        let isPlay = !this.data.isPlay;

        let { musicId, musicLink } = this.data;
        this.musicControl(isPlay, musicId, musicLink);
    },

    // 控制音乐播放/暂停的功能函数
    // 防止点击播放按钮多次发送数据请求，将获取到的音乐链接musicLink保存在data，下次请求做判断，如果相同的链接就用data中的。
    async musicControl(isPlay, musicId, musicLink) {
        if (isPlay) { // 播放
            if (!musicLink) { //当data中没有音乐链接musicLink的时候
                // 获取音乐的播放链接
                let musicLinkData = await request('/song/url', { id: musicId });
                musicLink = musicLinkData.data[0].url;
                this.setData({
                    musicLink
                });
            }

            // 不能给变量加''，不然会变成字符串！！！！
            this.backAudioManager.src = musicLink;
            this.backAudioManager.title = this.data.MusicDetail.name;
        } else { //暂停
            this.backAudioManager.pause();
        }
    },

    // 点击切歌的回调
    handlerSwitch(event) {
        // 获取切歌的类型
        let type = event.currentTarget.id;

        // 发布要准备切歌的消息之前，关闭当前音乐
        this.backAudioManager.stop();

        // 订阅来自recommendSong 页面发布的musicId消息
        PubSub.subscribe('musicId', (msg, musicId) => {
            // console.log(musicId);
            this.setData({
                musicId
            });

            // 获取音乐的详情信息
            this.getMusicDetail(musicId);

            // 自动播放当前的音乐
            // 切歌的时候没传 musicLink ，所以切歌的时候会进入musicControl方法的 if (!musicLink)中
            this.musicControl(true, musicId);

            // 取消订阅
            PubSub.unsubscribe('musicId')
        });

        // 发布消息数据给 recommendSong 页面
        PubSub.publish('switchType', type)
    },

    /**
     * 生命周期函数--监听页面初次渲染完成
     */
    onReady: function() {

    },

    /**
     * 生命周期函数--监听页面显示
     */
    onShow: function() {

    },

    /**
     * 生命周期函数--监听页面隐藏
     */
    onHide: function() {

    },

    /**
     * 生命周期函数--监听页面卸载
     */
    onUnload: function() {

    },

    /**
     * 页面相关事件处理函数--监听用户下拉动作
     */
    onPullDownRefresh: function() {

    },

    /**
     * 页面上拉触底事件的处理函数
     */
    onReachBottom: function() {

    },

    /**
     * 用户点击右上角分享
     */
    onShareAppMessage: function() {

    }
})